/**
******************************************************************************
* @file  HAL_exti.c
* @author  IC Applications Department
* @version  V0.8
* @date  2019_08_02
* @brief  This file provides all the EXTI firmware functions.
******************************************************************************
* @copy
*
* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE
* TIME. AS A RESULT, HOLOCENE SHALL NOT BE HELD LIABLE FOR ANY
* DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING
* FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE
* CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
*
* <h2><center>&copy; COPYRIGHT 2016 HOLOCENE</center></h2>
*/ 

/* Includes ------------------------------------------------------------------*/
#include "HAL_exti.h"

/** @addtogroup StdPeriph_Driver
* @{
*/

/** @defgroup EXTI 
* @brief EXTI driver modules
* @{
*/

/** @defgroup EXTI_Private_TypesDefinitions
* @{
*/

/**
* @}
*/

/** @defgroup EXTI_Private_Defines
* @{
*/

#define EXTI_LineNone    ((uint32_t)0x00000)  /* No interrupt selected */

/**
* @}
*/

/** @defgroup EXTI_Private_Macros
* @{
*/

/**
* @}
*/

/** @defgroup EXTI_Private_Variables
* @{
*/

/**
* @}
*/

/** @defgroup EXTI_Private_FunctionPrototypes
* @{
*/

/**
* @}
*/

/** @defgroup EXTI_Private_Functions
* @{
*/

/**
* @brief  Deinitializes the EXTI peripheral registers to their default 
*   reset values.
* @param  None
* @retval : None
*/
void EXTI_DeInit(void)
{
  EXTI->IMR = 0x00000000;
  EXTI->EMR = 0x00000000;
  EXTI->RTSR = 0x00000000; 
  EXTI->FTSR = 0x00000000; 
  EXTI->PR = 0x001FFFFF;
}

/**
* @brief  Initializes the EXTI peripheral according to the specified
*   parameters in the EXTI_InitStruct.
* @param EXTI_InitStruct: pointer to a EXTI_InitTypeDef structure
*   that contains the configuration information for the EXTI
*   peripheral.
* @retval : None
*/
void EXTI_Init(EXTI_InitTypeDef* EXTI_InitStruct)
{
  uint32_t tmp = 0;
  /* Check the parameters */
  assert_param(IS_EXTI_MODE(EXTI_InitStruct->EXTI_Mode));
  assert_param(IS_EXTI_TRIGGER(EXTI_InitStruct->EXTI_Trigger));
  assert_param(IS_EXTI_LINE(EXTI_InitStruct->EXTI_Line));  
  assert_param(IS_FUNCTIONAL_STATE(EXTI_InitStruct->EXTI_LineCmd));
  
  tmp = (uint32_t)EXTI_BASE;  
  
  if (EXTI_InitStruct->EXTI_LineCmd != DISABLE)
  {
    /* Clear EXTI line configuration */
    EXTI->IMR &= ~EXTI_InitStruct->EXTI_Line;
    EXTI->EMR &= ~EXTI_InitStruct->EXTI_Line;
    
    tmp += EXTI_InitStruct->EXTI_Mode;
    *(__IO uint32_t *) tmp |= EXTI_InitStruct->EXTI_Line;
    
    /* Clear Rising Falling edge configuration */
    EXTI->RTSR &= ~EXTI_InitStruct->EXTI_Line;
    EXTI->FTSR &= ~EXTI_InitStruct->EXTI_Line;
    
    /* Select the trigger for the selected external interrupts */
    if (EXTI_InitStruct->EXTI_Trigger == EXTI_Trigger_Rising_Falling)
    {
      /* Rising Falling edge */
      EXTI->RTSR |= EXTI_InitStruct->EXTI_Line;
      EXTI->FTSR |= EXTI_InitStruct->EXTI_Line;
    }
    else
    {
      tmp = (uint32_t)EXTI_BASE;
      tmp += EXTI_InitStruct->EXTI_Trigger;
      
      *(__IO uint32_t *) tmp |= EXTI_InitStruct->EXTI_Line;
    }
  }
  else
  {
    tmp = (uint32_t)EXTI_BASE;
    tmp += EXTI_InitStruct->EXTI_Mode;
    /* Disable the selected external lines */
    *(__IO uint32_t *) tmp &= ~EXTI_InitStruct->EXTI_Line;
  }
}

/**
* @brief  Fills each EXTI_InitStruct member with its reset value.
* @param EXTI_InitStruct: pointer to a EXTI_InitTypeDef structure
*   which will be initialized.
* @retval : None
*/
void EXTI_StructInit(EXTI_InitTypeDef* EXTI_InitStruct)
{
  EXTI_InitStruct->EXTI_Line = EXTI_LineNone;
  EXTI_InitStruct->EXTI_Mode = EXTI_Mode_Interrupt;
  EXTI_InitStruct->EXTI_Trigger = EXTI_Trigger_Falling;
  EXTI_InitStruct->EXTI_LineCmd = DISABLE;
}

/**
* @brief  Generates a Software interrupt.
* @param EXTI_Line: specifies the EXTI lines to be enabled or
*   disabled.
*   This parameter can be any combination of EXTI_Linex where 
*   x can be (0..18).
* @retval : None
*/
void EXTI_GenerateSWInterrupt(uint32_t EXTI_Line)
{
  /* Check the parameters */
  assert_param(IS_EXTI_LINE(EXTI_Line));
  
  EXTI->SWIER |= EXTI_Line;
}

/**
* @brief  Checks whether the specified EXTI line flag is set or not.
* @param EXTI_Line: specifies the EXTI line flag to check.
*   This parameter can be:
* @arg EXTI_Linex: External interrupt line x where x(0..18)
* @retval : The new state of EXTI_Line (SET or RESET).
*/
FlagStatus EXTI_GetFlagStatus(uint32_t EXTI_Line)
{
  FlagStatus bitstatus = RESET;
  /* Check the parameters */
  assert_param(IS_GET_EXTI_LINE(EXTI_Line));
  
  if ((EXTI->PR & EXTI_Line) != (uint32_t)RESET)
  {
    bitstatus = SET;
  }
  else
  {
    bitstatus = RESET;
  }
  return bitstatus;
}

/**
* @brief  Clears the EXTI�s line pending flags.
* @param EXTI_Line: specifies the EXTI lines flags to clear.
*   This parameter can be any combination of EXTI_Linex where 
*   x can be (0..18).
* @retval : None
*/
void EXTI_ClearFlag(uint32_t EXTI_Line)
{
  /* Check the parameters */
  assert_param(IS_EXTI_LINE(EXTI_Line));
  
  EXTI->PR = EXTI_Line;
}

/**
* @brief  Checks whether the specified EXTI line is asserted or not.
* @param EXTI_Line: specifies the EXTI line to check.
*   This parameter can be:
* @arg EXTI_Linex: External interrupt line x where x(0..18)
* @retval : The new state of EXTI_Line (SET or RESET).
*/
ITStatus EXTI_GetITStatus(uint32_t EXTI_Line)
{
  ITStatus bitstatus = RESET;
  uint32_t enablestatus = 0;
  /* Check the parameters */
  assert_param(IS_GET_EXTI_LINE(EXTI_Line));
  
  enablestatus =  EXTI->IMR & EXTI_Line;
  if (((EXTI->PR & EXTI_Line) != (uint32_t)RESET) && (enablestatus != (uint32_t)RESET))
  {
    bitstatus = SET;
  }
  else
  {
    bitstatus = RESET;
  }
  return bitstatus;
}

/**
* @brief  Clears the EXTI�s line pending bits.
* @param EXTI_Line: specifies the EXTI lines to clear.
*   This parameter can be any combination of EXTI_Linex where 
*   x can be (0..18).
* @retval : None
*/
void EXTI_ClearITPendingBit(uint32_t EXTI_Line)
{
  /* Check the parameters */
  assert_param(IS_EXTI_LINE(EXTI_Line));
  
  EXTI->PR = EXTI_Line;
}

/**
* @}
*/

/**
* @}
*/

/**
* @}
*/

/*-------------------------(C) COPYRIGHT 2016 HOLOCENE ----------------------*/
